"""
用户服务
负责用户管理、认证、权限控制等功能
"""

import hashlib
import secrets
import logging
from typing import Dict, Any, Optional, List
from datetime import datetime, timedelta
from ..models.user import User
from ..models.task import Task
from ..utils.validation_utils import ValidationUtils

logger = logging.getLogger(__name__)

class UserService:
    """用户服务类"""
    
    def __init__(self, app=None):
        self.app = app
        self.default_quota = app.config.get('DEFAULT_USER_QUOTA', 100) if app else 100
        self.session_timeout = app.config.get('SESSION_TIMEOUT_HOURS', 24) if app else 24
    
    def create_user(self, username: str, email: str, password: str, 
                   role: str = User.ROLE_USER) -> Dict[str, Any]:
        """
        创建新用户
        
        Args:
            username: 用户名
            email: 邮箱
            password: 密码
            role: 用户角色
            
        Returns:
            创建结果
        """
        try:
            # 验证输入数据
            validation_result = self._validate_user_data(username, email, password)
            if not validation_result['valid']:
                return {
                    'success': False,
                    'error': validation_result['error']
                }
            
            # 检查用户名和邮箱唯一性
            if User.find_by_username(username):
                return {'success': False, 'error': '用户名已存在'}
            
            if User.find_by_email(email):
                return {'success': False, 'error': '邮箱已被注册'}
            
            # 创建用户记录
            user_data = {
                'username': username,
                'email': email,
                'password_hash': self._hash_password(password),
                'role': role,
                'status': User.STATUS_ACTIVE,
                'quota': self._get_default_quota(role),
                'usage_stats': {
                    'total_tasks': 0,
                    'completed_tasks': 0,
                    'failed_tasks': 0,
                    'total_files_converted': 0,
                    'total_size_processed': 0
                },
                'preferences': {
                    'default_output_format': 'pdf',
                    'email_notifications': True,
                    'theme': 'light',
                    'language': 'zh-CN'
                },
                'created_at': datetime.utcnow(),
                'updated_at': datetime.utcnow(),
                'last_login': None
            }
            
            user_id = User.create(user_data)
            
            logger.info(f"用户创建成功: {user_id} - {username}")
            
            return {
                'success': True,
                'user_id': user_id,
                'username': username
            }
            
        except Exception as e:
            logger.error(f"用户创建失败: {str(e)}")
            return {
                'success': False,
                'error': f'用户创建失败: {str(e)}'
            }
    
    def authenticate_user(self, username: str, password: str) -> Dict[str, Any]:
        """
        用户认证
        
        Args:
            username: 用户名或邮箱
            password: 密码
            
        Returns:
            认证结果
        """
        try:
            # 查找用户（支持用户名或邮箱登录）
            user = User.find_by_username(username)
            if not user:
                user = User.find_by_email(username)
            
            if not user:
                return {'success': False, 'error': '用户不存在'}
            
            # 检查用户状态
            if user['status'] != User.STATUS_ACTIVE:
                return {'success': False, 'error': '用户账户已被禁用'}
            
            # 验证密码
            if not self._verify_password(password, user['password_hash']):
                return {'success': False, 'error': '密码错误'}
            
            # 更新最后登录时间
            User.update_by_id(user['_id'], {
                'last_login': datetime.utcnow(),
                'updated_at': datetime.utcnow()
            })
            
            # 生成会话令牌
            session_token = self._generate_session_token()
            
            logger.info(f"用户登录成功: {user['_id']} - {user['username']}")
            
            return {
                'success': True,
                'user': {
                    'id': str(user['_id']),
                    'username': user['username'],
                    'email': user['email'],
                    'role': user['role'],
                    'quota': user['quota'],
                    'preferences': user.get('preferences', {})
                },
                'session_token': session_token
            }
            
        except Exception as e:
            logger.error(f"用户认证失败: {str(e)}")
            return {'success': False, 'error': '认证失败'}
    
    def get_user_profile(self, user_id: str) -> Dict[str, Any]:
        """
        获取用户资料
        
        Args:
            user_id: 用户ID
            
        Returns:
            用户资料
        """
        try:
            user = User.find_by_id(user_id)
            if not user:
                return {'success': False, 'error': '用户不存在'}
            
            # 获取用户统计信息
            task_stats = Task.get_user_statistics(user_id)
            
            profile = {
                'id': str(user['_id']),
                'username': user['username'],
                'email': user['email'],
                'role': user['role'],
                'status': user['status'],
                'quota': user['quota'],
                'usage_stats': user.get('usage_stats', {}),
                'preferences': user.get('preferences', {}),
                'created_at': user['created_at'].isoformat() if user.get('created_at') else None,
                'last_login': user['last_login'].isoformat() if user.get('last_login') else None,
                'task_statistics': task_stats
            }
            
            return {'success': True, 'profile': profile}
            
        except Exception as e:
            logger.error(f"获取用户资料失败 {user_id}: {str(e)}")
            return {'success': False, 'error': str(e)}
    
    def update_user_profile(self, user_id: str, update_data: Dict[str, Any]) -> Dict[str, Any]:
        """
        更新用户资料
        
        Args:
            user_id: 用户ID
            update_data: 更新数据
            
        Returns:
            更新结果
        """
        try:
            user = User.find_by_id(user_id)
            if not user:
                return {'success': False, 'error': '用户不存在'}
            
            # 准备更新字段
            update_fields = {}
            
            # 可更新的基本字段
            for field in ['email']:
                if field in update_data:
                    if field == 'email':
                        # 验证邮箱格式
                        if not ValidationUtils.validate_email(update_data[field]):
                            return {'success': False, 'error': '邮箱格式不正确'}
                        
                        # 检查邮箱唯一性
                        existing_user = User.find_by_email(update_data[field])
                        if existing_user and existing_user['_id'] != user_id:
                            return {'success': False, 'error': '邮箱已被使用'}
                    
                    update_fields[field] = update_data[field]
            
            # 更新偏好设置
            if 'preferences' in update_data:
                current_preferences = user.get('preferences', {})
                new_preferences = {**current_preferences, **update_data['preferences']}
                update_fields['preferences'] = new_preferences
            
            if update_fields:
                update_fields['updated_at'] = datetime.utcnow()
                User.update_by_id(user_id, update_fields)
            
            logger.info(f"用户资料更新成功: {user_id}")
            
            return {'success': True, 'user_id': user_id}
            
        except Exception as e:
            logger.error(f"用户资料更新失败 {user_id}: {str(e)}")
            return {'success': False, 'error': str(e)}
    
    def change_password(self, user_id: str, old_password: str, new_password: str) -> Dict[str, Any]:
        """
        修改密码
        
        Args:
            user_id: 用户ID
            old_password: 旧密码
            new_password: 新密码
            
        Returns:
            修改结果
        """
        try:
            user = User.find_by_id(user_id)
            if not user:
                return {'success': False, 'error': '用户不存在'}
            
            # 验证旧密码
            if not self._verify_password(old_password, user['password_hash']):
                return {'success': False, 'error': '旧密码错误'}
            
            # 验证新密码
            if not ValidationUtils.validate_password(new_password):
                return {'success': False, 'error': '新密码格式不正确'}
            
            # 更新密码
            new_password_hash = self._hash_password(new_password)
            User.update_by_id(user_id, {
                'password_hash': new_password_hash,
                'updated_at': datetime.utcnow()
            })
            
            logger.info(f"密码修改成功: {user_id}")
            
            return {'success': True, 'message': '密码修改成功'}
            
        except Exception as e:
            logger.error(f"密码修改失败 {user_id}: {str(e)}")
            return {'success': False, 'error': str(e)}
    
    def check_quota(self, user_id: str) -> Dict[str, Any]:
        """
        检查用户配额
        
        Args:
            user_id: 用户ID
            
        Returns:
            配额信息
        """
        try:
            result = User.check_quota(user_id)
            
            return {
                'success': True,
                'quota_info': result
            }
            
        except Exception as e:
            logger.error(f"检查配额失败 {user_id}: {str(e)}")
            return {'success': False, 'error': str(e)}
    
    def update_usage_stats(self, user_id: str, task_completed: bool = False, 
                          file_size: int = 0) -> bool:
        """
        更新用户使用统计
        
        Args:
            user_id: 用户ID
            task_completed: 任务是否完成
            file_size: 文件大小
            
        Returns:
            是否更新成功
        """
        try:
            User.update_usage_stats(user_id, task_completed, file_size)
            return True
            
        except Exception as e:
            logger.error(f"更新使用统计失败 {user_id}: {str(e)}")
            return False
    
    def list_users(self, role: Optional[str] = None, status: Optional[str] = None,
                  limit: int = 50, offset: int = 0) -> Dict[str, Any]:
        """
        获取用户列表（管理员功能）
        
        Args:
            role: 角色过滤
            status: 状态过滤
            limit: 返回数量限制
            offset: 偏移量
            
        Returns:
            用户列表
        """
        try:
            users = User.list_users(role, status, limit, offset)
            total = User.count_users(role, status)
            
            # 移除敏感信息
            safe_users = []
            for user in users:
                safe_user = {
                    'id': str(user['_id']),
                    'username': user['username'],
                    'email': user['email'],
                    'role': user['role'],
                    'status': user['status'],
                    'quota': user['quota'],
                    'usage_stats': user.get('usage_stats', {}),
                    'created_at': user['created_at'].isoformat() if user.get('created_at') else None,
                    'last_login': user['last_login'].isoformat() if user.get('last_login') else None
                }
                safe_users.append(safe_user)
            
            return {
                'success': True,
                'users': safe_users,
                'total': total,
                'limit': limit,
                'offset': offset
            }
            
        except Exception as e:
            logger.error(f"获取用户列表失败: {str(e)}")
            return {'success': False, 'error': str(e)}
    
    def ban_user(self, user_id: str, admin_id: str, reason: str = '') -> Dict[str, Any]:
        """
        禁用用户
        
        Args:
            user_id: 用户ID
            admin_id: 管理员ID
            reason: 禁用原因
            
        Returns:
            操作结果
        """
        try:
            # 验证管理员权限
            admin = User.find_by_id(admin_id)
            if not admin or admin['role'] != User.ROLE_ADMIN:
                return {'success': False, 'error': '无权限执行此操作'}
            
            # 禁用用户
            result = User.ban_user(user_id, reason)
            
            if result:
                logger.info(f"用户禁用成功: {user_id} by {admin_id}")
                return {'success': True, 'user_id': user_id}
            else:
                return {'success': False, 'error': '禁用用户失败'}
            
        except Exception as e:
            logger.error(f"禁用用户失败 {user_id}: {str(e)}")
            return {'success': False, 'error': str(e)}
    
    def unban_user(self, user_id: str, admin_id: str) -> Dict[str, Any]:
        """
        解禁用户
        
        Args:
            user_id: 用户ID
            admin_id: 管理员ID
            
        Returns:
            操作结果
        """
        try:
            # 验证管理员权限
            admin = User.find_by_id(admin_id)
            if not admin or admin['role'] != User.ROLE_ADMIN:
                return {'success': False, 'error': '无权限执行此操作'}
            
            # 解禁用户
            result = User.unban_user(user_id)
            
            if result:
                logger.info(f"用户解禁成功: {user_id} by {admin_id}")
                return {'success': True, 'user_id': user_id}
            else:
                return {'success': False, 'error': '解禁用户失败'}
            
        except Exception as e:
            logger.error(f"解禁用户失败 {user_id}: {str(e)}")
            return {'success': False, 'error': str(e)}
    
    def delete_user(self, user_id: str, admin_id: str) -> Dict[str, Any]:
        """
        删除用户（软删除）
        
        Args:
            user_id: 用户ID
            admin_id: 管理员ID
            
        Returns:
            操作结果
        """
        try:
            # 验证管理员权限
            admin = User.find_by_id(admin_id)
            if not admin or admin['role'] != User.ROLE_ADMIN:
                return {'success': False, 'error': '无权限执行此操作'}
            
            # 不能删除自己
            if user_id == admin_id:
                return {'success': False, 'error': '不能删除自己的账户'}
            
            # 软删除用户
            result = User.soft_delete(user_id)
            
            if result:
                logger.info(f"用户删除成功: {user_id} by {admin_id}")
                return {'success': True, 'user_id': user_id}
            else:
                return {'success': False, 'error': '删除用户失败'}
            
        except Exception as e:
            logger.error(f"删除用户失败 {user_id}: {str(e)}")
            return {'success': False, 'error': str(e)}
    
    def get_user_statistics(self) -> Dict[str, Any]:
        """
        获取用户统计信息
        
        Returns:
            统计信息
        """
        try:
            stats = User.get_statistics()
            
            return {'success': True, 'statistics': stats}
            
        except Exception as e:
            logger.error(f"获取用户统计失败: {str(e)}")
            return {'success': False, 'error': str(e)}
    
    def _validate_user_data(self, username: str, email: str, password: str) -> Dict[str, Any]:
        """验证用户数据"""
        if not ValidationUtils.validate_username(username):
            return {'valid': False, 'error': '用户名格式不正确'}
        
        if not ValidationUtils.validate_email(email):
            return {'valid': False, 'error': '邮箱格式不正确'}
        
        if not ValidationUtils.validate_password(password):
            return {'valid': False, 'error': '密码格式不正确'}
        
        return {'valid': True}
    
    def _hash_password(self, password: str) -> str:
        """密码哈希"""
        salt = secrets.token_hex(16)
        password_hash = hashlib.pbkdf2_hmac('sha256', password.encode(), salt.encode(), 100000)
        return f"{salt}:{password_hash.hex()}"
    
    def _verify_password(self, password: str, password_hash: str) -> bool:
        """验证密码"""
        try:
            salt, stored_hash = password_hash.split(':')
            password_hash_check = hashlib.pbkdf2_hmac('sha256', password.encode(), salt.encode(), 100000)
            return password_hash_check.hex() == stored_hash
        except Exception:
            return False
    
    def _generate_session_token(self) -> str:
        """生成会话令牌"""
        return secrets.token_urlsafe(32)
    
    def _get_default_quota(self, role: str) -> Dict[str, int]:
        """获取默认配额"""
        if role == User.ROLE_ADMIN:
            return {
                'daily_tasks': 1000,
                'monthly_tasks': 30000,
                'max_file_size': 100 * 1024 * 1024,  # 100MB
                'concurrent_tasks': 10
            }
        elif role == User.ROLE_PREMIUM:
            return {
                'daily_tasks': 200,
                'monthly_tasks': 5000,
                'max_file_size': 50 * 1024 * 1024,  # 50MB
                'concurrent_tasks': 5
            }
        else:  # USER
            return {
                'daily_tasks': 20,
                'monthly_tasks': 500,
                'max_file_size': 10 * 1024 * 1024,  # 10MB
                'concurrent_tasks': 2
            }
    
    def reset_password_request(self, email: str) -> Dict[str, Any]:
        """
        请求重置密码
        
        Args:
            email: 邮箱地址
            
        Returns:
            请求结果
        """
        try:
            user = User.find_by_email(email)
            if not user:
                # 为了安全，不透露用户是否存在
                return {'success': True, 'message': '如果邮箱存在，重置链接已发送'}
            
            # 生成重置令牌
            reset_token = secrets.token_urlsafe(32)
            expires_at = datetime.utcnow() + timedelta(hours=1)  # 1小时有效期
            
            # 保存重置令牌
            User.update_by_id(user['_id'], {
                'reset_token': reset_token,
                'reset_token_expires': expires_at,
                'updated_at': datetime.utcnow()
            })
            
            # TODO: 发送重置邮件
            logger.info(f"密码重置请求: {email}")
            
            return {'success': True, 'message': '重置链接已发送到您的邮箱'}
            
        except Exception as e:
            logger.error(f"密码重置请求失败: {str(e)}")
            return {'success': False, 'error': '请求失败，请稍后重试'}
    
    def reset_password(self, token: str, new_password: str) -> Dict[str, Any]:
        """
        重置密码
        
        Args:
            token: 重置令牌
            new_password: 新密码
            
        Returns:
            重置结果
        """
        try:
            # 查找有效的重置令牌
            user = User.find_one({
                'reset_token': token,
                'reset_token_expires': {'$gt': datetime.utcnow()}
            })
            
            if not user:
                return {'success': False, 'error': '重置链接无效或已过期'}
            
            # 验证新密码
            if not ValidationUtils.validate_password(new_password):
                return {'success': False, 'error': '新密码格式不正确'}
            
            # 更新密码并清除重置令牌
            new_password_hash = self._hash_password(new_password)
            User.update_by_id(user['_id'], {
                'password_hash': new_password_hash,
                'reset_token': None,
                'reset_token_expires': None,
                'updated_at': datetime.utcnow()
            })
            
            logger.info(f"密码重置成功: {user['_id']}")
            
            return {'success': True, 'message': '密码重置成功'}
            
        except Exception as e:
            logger.error(f"密码重置失败: {str(e)}")
            return {'success': False, 'error': '重置失败，请稍后重试'}